package com.block.api.controller.product;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.block.common.annotate.NeedToken;
import com.block.common.bean.CommonParam;
import com.block.common.bean.SessionBean;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.enums.AppRspCodeEnum;
import com.block.common.exception.ApiException;
import com.block.common.security.util.ApiUtil;
import com.block.common.util.LocalDateUtil;
import com.block.common.vo.ResponseVo;
import com.block.db.entity.AppEncrypt;
import com.block.db.entity.ApplicationInfo;
import com.block.db.entity.ChannelBaseInfo;
import com.block.product.model.dto.ProductClickDTO;
import com.block.product.service.IProductBaseInfoService;
import com.block.product.service.IProductOnlieInfoService;
import com.block.product.service.IProductProfitUvInfoService;
import com.block.product.service.IProductUnionResultInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("api/product")
@Validated
public class ProductController {

    @Autowired
    IProductOnlieInfoService productOnlieInfoService;
    @Autowired
    IProductProfitUvInfoService productProfitUvInfoService;
    @Autowired
    IProductUnionResultInfoService productUnionResultInfoService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    IProductBaseInfoService productBaseInfoService;

    /**
     * 产品列表信息
     *
     */
    @NeedToken
    @RequestMapping(value = "/prodInfoList", method = {RequestMethod.POST, RequestMethod.GET})
    public String prodInfoList(@RequestAttribute(value = "tranData") JSONObject tranData,
                          @RequestAttribute(value = "appEncrypt") AppEncrypt appEncrypt,
                            @RequestAttribute(value = "channelBaseInfo") ChannelBaseInfo channelBaseInfo,
                            @RequestAttribute(value = "applicationInfo") ApplicationInfo applicationInfo,
                            @RequestAttribute(value = "sessionBean") SessionBean sessionBean,
                            @RequestAttribute(value = "uri") String uri,
                            @RequestAttribute(value = "startDate") Date startdate,
                            @RequestAttribute(value = "ip") String ip) throws ApiException {

        String sceneId = tranData.getString("sceneId");

        ResponseVo responseVo = productOnlieInfoService.prodInfoList(channelBaseInfo, sceneId, sessionBean.getUid(), ip);
        return ApiUtil.dealReturnJson(responseVo, appEncrypt, startdate, uri);
    }

    /**
     * 产品点击统计
     *
     */
    @NeedToken
    @RequestMapping(value = "/prodClickCount", method = {RequestMethod.POST, RequestMethod.GET})
    public String prodClickCount(HttpServletRequest request,
                                 @RequestAttribute(value = "tranData") JSONObject tranData,
                                 @RequestAttribute(value = "appEncrypt") AppEncrypt appEncrypt,
                                 @RequestAttribute(value = "channelBaseInfo") ChannelBaseInfo channelBaseInfo,
                                 @RequestAttribute(value = "applicationInfo") ApplicationInfo applicationInfo,
                                 @RequestAttribute(value = "sessionBean") SessionBean sessionBean,
                                 @RequestAttribute(value = "commonParam") CommonParam commonParam,
                                 @RequestAttribute(value = "uri") String uri,
                                 @RequestAttribute(value = "startDate") Date startdate,
                                 @RequestAttribute(value = "ip") String ip) throws ApiException {

        String productId = tranData.getString("productId");
        String userAgentStr = request.getHeader("User-Agent");

        ProductClickDTO productClickDTO = new ProductClickDTO();
        productClickDTO.setProductId(productId);
        productClickDTO.setReqIp(ip);
        productClickDTO.setUserAgent(userAgentStr);
        productClickDTO.setRandomId(commonParam.getRandomUuid());
        productClickDTO.setUid(sessionBean.getUid());

        ResponseVo responseVo = productProfitUvInfoService.countProductClick(productClickDTO, channelBaseInfo, applicationInfo);
        return ApiUtil.dealReturnJson(responseVo, appEncrypt, startdate, uri);
    }

    /**
     * 获取产品联登结果
     *
     */
    @NeedToken
    @RequestMapping(value = "/getProdUnionResult", method = {RequestMethod.POST, RequestMethod.GET})
    public String getProdUnionResult(@RequestAttribute(value = "tranData") JSONObject tranData,
                           @RequestAttribute(value = "appEncrypt") AppEncrypt appEncrypt,
                           @RequestAttribute(value = "channelBaseInfo") ChannelBaseInfo channelBaseInfo,
                           @RequestAttribute(value = "applicationInfo") ApplicationInfo applicationInfo,
                           @RequestAttribute(value = "sessionBean") SessionBean sessionBean,
                           @RequestAttribute(value = "uri") String uri,
                           @RequestAttribute(value = "startDate") Date startdate,
                           @RequestAttribute(value = "ip") String ip) throws ApiException {

        String productId = tranData.getString("productId");
        String redisKey = StrUtil.format("{}-{}", productId, sessionBean.getUid());

        ResponseVo responseVo = productUnionResultInfoService.getProdUnionResult(productId, sessionBean.getUid(), redisKey,channelBaseInfo);
        return ApiUtil.dealReturnJson(responseVo, appEncrypt, startdate, uri);
    }

    /**
     *
     * 用户匹配失败返回uv价格最高的产品,依次递减
     */
    @NeedToken
    @RequestMapping(value = "/getOptimalProduct", method = {RequestMethod.POST, RequestMethod.GET})
    public String getOptimalProduct(@RequestAttribute(value = "tranData") JSONObject tranData,
                               @RequestAttribute(value = "appEncrypt") AppEncrypt appEncrypt,
                               @RequestAttribute(value = "channelBaseInfo") ChannelBaseInfo channelBaseInfo,
                               @RequestAttribute(value = "applicationInfo") ApplicationInfo applicationInfo,
                               @RequestAttribute(value = "sessionBean") SessionBean sessionBean,
                               @RequestAttribute(value = "uri") String uri,
                               @RequestAttribute(value = "startDate") Date startdate,
                               @RequestAttribute(value = "ip") String ip) throws ApiException {

        String sceneId = tranData.getString("sceneId");

        ResponseVo responseVo = productOnlieInfoService.getOptimalProduct(channelBaseInfo, sceneId, sessionBean.getUid(), ip);
        return ApiUtil.dealReturnJson(responseVo, appEncrypt, startdate, uri);
    }

    @NeedToken
    @RequestMapping(value = "/getLoanOverProduct", method = {RequestMethod.POST, RequestMethod.GET})
    public String getLoanOverProduct(@RequestAttribute(value = "tranData") JSONObject tranData,
                                    @RequestAttribute(value = "appEncrypt") AppEncrypt appEncrypt,
                                    @RequestAttribute(value = "channelBaseInfo") ChannelBaseInfo channelBaseInfo,
                                    @RequestAttribute(value = "applicationInfo") ApplicationInfo applicationInfo,
                                    @RequestAttribute(value = "sessionBean") SessionBean sessionBean,
                                    @RequestAttribute(value = "uri") String uri,
                                    @RequestAttribute(value = "startDate") Date startdate,
                                    @RequestAttribute(value = "ip") String ip) throws ApiException {

        String sceneId = tranData.getString("sceneId");

        ResponseVo responseVo = productOnlieInfoService.getLoanOverProduct(channelBaseInfo, sceneId, sessionBean.getUid());
        return ApiUtil.dealReturnJson(responseVo, appEncrypt, startdate, uri);
    }

    @NeedToken
    @RequestMapping(value = "/getCache", method = {RequestMethod.POST, RequestMethod.GET})
    public String getCache(@RequestAttribute(value = "tranData") JSONObject tranData,
                                     @RequestAttribute(value = "appEncrypt") AppEncrypt appEncrypt,
                                     @RequestAttribute(value = "channelBaseInfo") ChannelBaseInfo channelBaseInfo,
                                     @RequestAttribute(value = "applicationInfo") ApplicationInfo applicationInfo,
                                     @RequestAttribute(value = "sessionBean") SessionBean sessionBean,
                                     @RequestAttribute(value = "uri") String uri,
                                     @RequestAttribute(value = "startDate") Date startdate,
                                     @RequestAttribute(value = "ip") String ip) throws ApiException {

        String productId = tranData.getString("productId");
        String redisIdKey = RedisKeyConstant.PRODUCT_OVER_ID + sessionBean.getUid();
        Long remainSecondNumber = LocalDateUtil.getRemainSecondNumber();
        stringRedisTemplate.opsForSet().add(redisIdKey, productId);
        stringRedisTemplate.expire(redisIdKey, remainSecondNumber, TimeUnit.SECONDS);
        ResponseVo responseVo = new ResponseVo();
        responseVo.setRspCode(AppRspCodeConstant.SUCCESS);
        return ApiUtil.dealReturnJson(responseVo, appEncrypt, startdate, uri);

    }

    @RequestMapping(value = "/push/merchant/apis", method = {RequestMethod.POST,RequestMethod.GET})
    public String pushMerchantApis(@RequestAttribute(value = "tranData") JSONObject tranData,
                                   @RequestAttribute(value = "appEncrypt") AppEncrypt appEncrypt,
                                   @RequestAttribute(value = "channelBaseInfo") ChannelBaseInfo channelBaseInfo,
                                   @RequestAttribute(value = "applicationInfo") ApplicationInfo applicationInfo,
                                   @RequestAttribute(value = "uri") String uri,
                                   @RequestAttribute(value = "startDate") Date startdate,
                                   @RequestAttribute(value = "ip") String ip) throws Exception{

        ResponseVo responseVo = productBaseInfoService.pushMerchantApis();
        return ApiUtil.dealReturnJson(responseVo, appEncrypt, startdate, uri);
    }
}
